home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9207.ZIP / QUICKT.ASC < prev    next >
Text File  |  1992-06-15  |  22KB  |  504 lines

  1. _PROGRAMMING QUICKTIME_
  2. by Aaron Walsh
  3.  
  4. [LISTING ONE]
  5.  
  6. /*****************************************************************************
  7. * MoviePlayer Application -- This QuickTime program demonstrates how to open a 
  8. *   movie file using a file preview dialog, add a movie controller to the 
  9. *   movie, and play a movie in a window. Author: Aaron E. Walsh
  10. *   Developed using Think C 5.0, & QuickTime headers
  11. ******************************************************************************/
  12.  
  13. #include <Movies.h>
  14. #include <QuickTimeComponents.h>
  15. #include <GestaltEqu.h>
  16. #include <Quickdraw.h>
  17. #include <StandardFile.h>
  18. #include <OSEvents.h>
  19.  
  20. /***** Global Variables ******/
  21. Boolean     gSys7Preview;   /* is System 7  Preview routine available*/
  22.  
  23. Movie           theMovie;       /* info about the movie returned by OpenMovie*/
  24. Rect            dispBounds;
  25. MovieController myMovieController;  /* controller component for movie*/
  26.  
  27. WindowPtr       movieWindow;    /* window to play the movie in */
  28. OSErr           error;                  
  29.  
  30. /* Variables used in opening a movie file: */
  31. FSSpec      mySpec;     /* File System record for System 6 */
  32. short           resRefNum;  /* Resource reference # of selected file */
  33.         
  34. SFTypeList      ypes  = {'MooV'}; /* show files of type 'Moov' */
  35. short           numtypes = 1;   
  36.  
  37. StandardFileReply   fReply;  /* Standard File Reply (Sys. 7/QuickTime) */
  38. SFReply         oldfReply; /* old style (Sys.6) Standard File Reply */
  39.  
  40. EventRecord     *theEvent;              
  41.  
  42. /****** Prototypes ******/
  43. Boolean         QuickTimeCapable(void);  /* is system QT capable? */
  44. StandardFileReply   GetMovie(void);  /* user select movie file to play */
  45. void            PlayMovie(void); /* play the movie */
  46. void            MakeMovieController(void); /* find controller . */
  47. void            ShowMovieController(void); /* attach controller */
  48.  
  49. /*****************************************************************************
  50. * main() -- Initialize standard Macintosh toolbox managers, check if QuickTime 
  51. *   is available, execute small loop prompting user for movies to play. Exit
  52. *   when user selects "Cancel" from preview dialog.
  53. *****************************************************************************/
  54. main()
  55. {   
  56.     /* Initialize Toolbox Managers and data structures: */  
  57.     MaxApplZone();              
  58.     InitGraf(&qd.thePort);
  59.     FlushEvents(everyEvent, 0);
  60.     InitWindows();
  61.     InitCursor();
  62. if (QuickTimeCapable()) {
  63.     do {
  64.         fReply = GetMovie(); /* prompt user for a movie file to play */
  65.         if (fReply.sfGood)
  66.             PlayMovie(); /* play the selected movie. */
  67.             } while (fReply.sfGood); 
  68.         ExitMovies(); }                 
  69.     else 
  70.         ;   /* QuickTime is not available.  Normally you would  
  71.             /* put up an error message for user. */
  72. }
  73.  
  74. /****************************************************************************
  75. * GetMovie() -- Allow user to select a movie file to play (file of type 
  76. *    'Moov') using StandardGetFilePreview routine.
  77. *****************************************************************************/
  78. StandardFileReply GetMovie()
  79. {
  80.     Point   where;      /* for System 6 preview */
  81. if (gSys7Preview) 
  82. StandardGetFilePreview(0, numtypes, types, &fReply); /* Sys 7 preview dialog */
  83.  
  84. else {                  /* using Sys 6 */
  85.     where.h = where.v = -2; /* center dialog on screen w/"best" display */
  86.     SFGetFilePreview(where, 0l, 0l, numtypes, types, 0l, &oldfReply); 
  87.     fReply.sfGood = oldfReply.good;
  88.     if (fReply.sfGood)       /* convert the reply record into an FSSpec: */
  89.         FSMakeFSSpec(oldfReply.vRefNum, 0, oldfReply.fName, &mySpec);
  90.     }
  91. return (fReply); 
  92. }
  93.  
  94. /****************************************************************************
  95. * MakeMovieController() -- Uses the Component Manager to locate the default 
  96. *   movie controller, where it is then displayed at bottom of movie window.
  97. *****************************************************************************/
  98. void MakeMovieController()
  99. {
  100.     Component           standardMovieController;
  101.     ComponentDescription    controllerDescription;
  102.     ComponentResult     theErr;
  103.     Point               thePoint;
  104.     Rect                controllerBox;
  105.     /* Fill in component descriptor fields.  This info is used by the 
  106.      * Component Manager to locate a corresponding component. We are 
  107.          * looking for the standard movie controller component:  */
  108.     controllerDescription.componentType = 'play';
  109.     controllerDescription.componentSubType = 0;
  110.     controllerDescription.componentManufacturer = 0;
  111.     controllerDescription.componentFlags = 0;
  112.     controllerDescription.componentFlagsMask = 0;
  113.     
  114. standardMovieController = FindNextComponent( (Component) 0,
  115.                                                       &controllerDescription);
  116.     /* Get the controller */
  117.     myMovieController = OpenComponent(standardMovieController);
  118.  
  119.     if(myMovieController == 0l) 
  120.         return;            /* return to caller if this is the case */
  121.     /* Place controller in the movie window */
  122.     thePoint.h = movieWindow->portRect.left;
  123.     thePoint.v = movieWindow->portRect.top;  
  124.     
  125. theErr = MCNewAttachedController(myMovieController,theMovie, movieWindow,
  126.                                                                     thePoint);
  127.     if (theErr != 0)
  128.         return;
  129.     ShowMovieController();              
  130. }
  131.         
  132. /*****************************************************************************
  133. * ShowMovieController() -- Adjusts size of movie window so movie and movie 
  134. *   controller are viewable
  135. *****************************************************************************/
  136. void ShowMovieController()
  137. {
  138.     Rect    movieBox, controllerBox;
  139. /* Adjust size of movie window to accomodate both movie and movie controller */
  140. MCGetControllerBoundsRect(myMovieController,&controllerBox); 
  141. /* Adjust movieBox to accomodate controller: */
  142. UnionRect(&movieBox,&controllerBox,&movieBox);
  143. /* Resize movie window: */
  144. SizeWindow( movieWindow,movieBox.right,movieBox.bottom,true);   
  145. }           
  146.  
  147. /****************************************************************************
  148. * PlayMovie() -- Opens the appropriate movie file (file of type 'MooV'), 
  149. *   create a window large enough to fit the movie, and play the movie.
  150. *****************************************************************************/
  151. void PlayMovie()
  152. {
  153.     FSSpec  movieFSSpec;
  154.     /* First open the movie file */
  155.     if (gSys7Preview) 
  156.         movieFSSpec = fReply.sfFile;   
  157.     else
  158.         movieFSSpec = mySpec;    
  159.     if ((error = OpenMovieFile(&movieFSSpec, &resRefNum, 0)) != noErr)
  160.         return; /* if error occured, exit PlayMovie() */
  161.     if ((error = NewMovieFromFile( &theMovie,resRefNum, nil, nil,0, nil )) 
  162.                                                                       != noErr)
  163.         return; /* if error occured, exit  PlayMovie() */
  164.     /* Find movie bounds and set top left to 0,0 so */
  165.     /* the movie will be properly postioned in our window   */
  166.     GetMovieBox(theMovie, &dispBounds);
  167.     OffsetRect(&dispBounds,-dispBounds.left,-dispBounds.top);
  168.     SetMovieBox(theMovie, &dispBounds); 
  169.  
  170.     OffsetRect(&dispBounds,50,50);  /* window rect can't hit menu bar */
  171.     movieWindow = NewCWindow(0L,&dispBounds,0l,true,0,(WindowPtr)-1L,
  172.                                     false,0L);     /* window for our movie*/
  173.     SetPort(movieWindow);
  174.     SetMovieGWorld(theMovie,nil,nil); 
  175.     MakeMovieController();  /* routine for creating standard controller */
  176.     /* After setup, play the movie: */
  177.     GoToBeginningOfMovie(theMovie); /* rewind movie to beginning */
  178.     PrerollMovie(theMovie,0,0); /* preload portions of movie */
  179.     SetMovieActive(theMovie,true);  /* set movie to active for servicing */
  180.     
  181.     /* Use controller to play movie until it is finished. Events are 
  182.            passed to MCIsPlayerEvent which handles controller events: */        
  183.     while ( !IsMovieDone(theMovie)) {
  184.         GetNextEvent(everyEvent, theEvent);
  185.         MCIsPlayerEvent(myMovieController, theEvent);
  186.         }
  187.     /* dispose of storage, and return */
  188.     DisposeMovie(theMovie);        /* movie */
  189.     CloseMovieFile(resRefNum);     /* reference to movie file */
  190.     CloseComponent(myMovieController); /* movie controller */
  191.     DisposeWindow(movieWindow);
  192. }   
  193.  
  194. /****************************************************************************
  195. * QuickTimeCapable() -- Uses Gestalt Manager to check if QuickTime is 
  196. *   available at runtime. If not, return error. 
  197. *****************************************************************************/
  198. Boolean QuickTimeCapable() 
  199. {
  200.     long    response;
  201.         /* Test if QuickTime is available: */
  202.     error = Gestalt(gestaltQuickTime, &response);
  203.         if (error != 0)   /* error=0 if OK, else error has occured */
  204.             return false;   /* if error, return */
  205.     
  206. /* if no error finding QuickTime, check for ICM so we can use Stand.Preview  */
  207.     error = Gestalt(gestaltCompressionMgr, &response);
  208.         if (error != 0)
  209.           return false; /* Can't use Stand.Preview routines */
  210.     error = Gestalt(gestaltStandardFileAttr, &response);
  211.     if (error != 0)    /* if not available, we're playing under System 6 */
  212.         gSys7Preview = false; 
  213.     else
  214.         gSys7Preview = true;       /* use System 7 standard preview */
  215.     error = EnterMovies();  /* Initialize Movie Toolbox & return result */
  216.     if (error != 0)
  217.         return false;   /* error initalizing QuickTime  */
  218.     else
  219.         return true;    /* QuickTimes available, ready to play movies*/
  220. }           
  221.     
  222.  
  223.  
  224. [LISTING TWO]
  225.  
  226. /*****************************************************************************
  227. * MovieMaker Application -- This QuickTime program demonstrates how to create 
  228. *   a QuickTime movie with associated track and media. The Movie Toolbox, 
  229. *   Component Manager, and Image Compression Manager (ICM) are demonstrated.
  230. *   Author:  Aaron E. Walsh -- Developed using Think C 5.0, & QuickTime headers
  231. *****************************************************************************/
  232.  
  233. #include <Movies.h>
  234. #include <QuickTimeComponents.h>
  235. #include <ImageCompression.h>
  236. #include <GestaltEqu.h>
  237. #include <Quickdraw.h>
  238.  
  239. /****** defines ******/
  240. #define kFrameX 150 /* x-coord/width*/
  241. #define kFrameY 125 /* y-coord/height */
  242. #define kPixelDepth 32  /* depth for GWorld */
  243. #define kFrameTotal 30  /* total frames in movie */
  244. #define kTimeScale 15   /* desired frames per second    */
  245. #define kFrameRate (Fixed) 1<<16 /* fixed point 1.00 = our frame rate */
  246.  
  247. /****** Types and globals ******/
  248. /*  general:    */
  249. OSErr           error;          
  250. Rect            frmRect;                
  251. /* movie file:  */          
  252. Movie           gMovie;         /* our movie,   */
  253. Track           gTrack;         /* track,   */
  254. Media           gMedia;         /* and media    */
  255. short           resRefNum;
  256. StandardFileReply   fReply;                         
  257. FSSpec      movieFSSpec;        /* FFSpec reference to movie file */
  258. /* image data: */
  259. char            **frameDatabitsH;   /* buffer for compressed frames */
  260. ImageDescription    **imageDescriptionH;/* image info used by compressor */
  261. PixMap      *pixMap,**pixMapH;      /* offscreen pixmaps */
  262.  
  263. /* graphics world: */
  264. GWorldPtr       movieGWorld,oldGWorld;  /* offscreen grapics worlds */
  265. GDHandle        oldGDevice;             
  266. /* compressor:*/
  267. long            compressedFrameSize;  /* size of compressed frame */
  268. CodecType       codecType;        /* desired codec */
  269. CompressorComponent codecID;          /* variation of codecType */
  270. short           colorDepth;       /* depth to compress image to*/
  271. CodecQ              imageQuality;         /* desired compression quality*/
  272.  
  273. /* media sample: */
  274. TimeValue       sampTime;   /* generated when adding sample to media */
  275.  
  276. /****** Prototypes ******/
  277. void        BuildMovie(void);     /* main routine to assemble a movie */
  278. void        MakeMovieFile(void);  /* create movie file and movie itself */
  279. void        MakeMovieGWorld(void);/* allocate offscreen graphics environ */
  280. void        AllocateMovieBuffer(void); /* allocate storage for frames*/
  281. void        MakeMovieFrames(void);  /* loop to create all movie frames */
  282. void        AddMovieFrame(void);  /* compress & add single frame to media*/
  283. void        CleanUp(void);       /* free allocated storage, make preview */
  284. void        main(void);
  285.  
  286. /*****************************************************************************
  287. * main() -- Initialize standard Macintosh toolbox managers, check if QuickTime 
  288.    capable and call BuildMovie() to create our movie.
  289. ******************************************************************************/
  290. void main(void)
  291. {   
  292.     /* Initialize Toolbox Managers and data structures: */  
  293.     MaxApplZone();              
  294.     InitGraf(&qd.thePort);
  295.     FlushEvents(everyEvent, 0);
  296.     InitWindows();
  297.     InitCursor();
  298.     if (QuickTimeCapable()) {
  299.         BuildMovie();       /* create the movie */  
  300.     }   
  301. }
  302.  
  303. /*****************************************************************************
  304. * BuildMovie() -- Sets up display window for movie frames, and calls 
  305. *   appropriate routines for creating movie.
  306. *****************************************************************************/
  307. void BuildMovie(void)
  308. {
  309.     WindowPtr displayWind;
  310.     Rect windRect;
  311.     windRect.left = windRect.top = 0;
  312.     windRect.right = kFrameX;
  313.     windRect.bottom = kFrameY;
  314.     OffsetRect(&windRect,150,50);
  315. displayWind = NewCWindow(0,&windRect,(StringPtr)"\pMovie Window",true,0,
  316.                                                          (WindowPtr)-1,true,0);
  317.     SetPort(displayWind);
  318.     ClearMoviesStickyError();   /* clear any old movie errors   */
  319.     while (!GetMoviesStickyError()) {
  320.         MakeMovieFile();    /*create actual movie file on disk */
  321.         MakeMovieGWorld();  /*set up graphics devices for images */
  322.         AllocateMovieBuffer();  /*allocate buffer space */
  323.         MakeMovieFrames();  /*create, compress & add frames */
  324.         CleanUp();          /* create preview & release storage */
  325.     }
  326.     CloseWindow(displayWind);   /* close display window */
  327. }
  328.  
  329. /*****************************************************************************
  330. * MakeMovieFile() -- Create a new movie file (gMovie) with associated track 
  331. *   (gTrack) and media (gMedia).  
  332. *****************************************************************************/
  333. void    MakeMovieFile(void) {
  334. /* StandardPutFile prompt; create movie file */
  335. StandardPutFile((StringPtr) "\pCreate Movie File:",
  336.                                             (StringPtr)"\pNew Movie",&fReply);
  337.     if (!fReply.sfGood) 
  338.         return;
  339.     movieFSSpec = fReply.sfFile;    /* reference to our movie file*/
  340. error = CreateMovieFile( &movieFSSpec,'MPLA',0,createMovieFileDeleteCurFile,
  341.                                                            &resRefNum,&gMovie);
  342.     if (error) ExitToShell(); 
  343. /* Create track and media */
  344.     gTrack = NewMovieTrack(gMovie,(long)kFrameX<<16,(long)kFrameY<<16,0);
  345.     error = GetMoviesError();
  346.     if (error) ExitToShell();
  347. gMedia = NewTrackMedia(gTrack, VideoMediaType, kTimeScale, nil,(OSType) nil);
  348.     error = GetMoviesError();
  349.     if (error) ExitToShell();
  350.     error = BeginMediaEdits( gMedia ); /* needed to add samples to media */
  351.     if (error) ExitToShell(); 
  352. }
  353.  
  354. /*****************************************************************************
  355. * MakeMovieGWorld() -- Make a GWorld (offscreen graphics world) for movie. 
  356. *****************************************************************************/
  357. void MakeMovieGWorld(void) {
  358.     GetGWorld(&oldGWorld,&oldGDevice);/* save old graphics world/device*/
  359.     frmRect.left = frmRect.top = 0; /* setup size of frame*/ 
  360.     frmRect.right = (short)(kFrameX);
  361.     frmRect.bottom = (short)(kFrameY);
  362. /*create movieGWorld: */
  363.     error = NewGWorld(&movieGWorld,kPixelDepth,&frmRect,nil,nil,0); 
  364.     if (error) ExitToShell();
  365.  /* get handle to pixMap of movieGWorld: */
  366.     pixMapH = GetGWorldPixMap(movieGWorld);
  367. /* lock offscreen pixMap in memory:*/
  368.     LockPixels(pixMapH);    
  369. /* lock handle to prevent dangling reference:*/
  370.     HLock((Handle)pixMapH); 
  371.     pixMap = *pixMapH;  /* make pointer (pixMap) to pixel-map*/
  372. }
  373.  
  374. /*****************************************************************************
  375. * AllocateMovieBuffer() -- Allocate frame buffer according to our requested
  376. *   compression level.
  377. *****************************************************************************/
  378. void AllocateMovieBuffer(void) {
  379. long        maxCompressedFrameSize; /* Max size of a compressed frame*/
  380.  
  381. /*  compressor info: */ 
  382.     codecID = anyCodec;
  383.     codecType = (CodecType) 'rpza'; /* use video compression */
  384.     colorDepth = 1;         /* compress to 1 bit depth */
  385.     imageQuality = codecNormalQuality;/* quality range is 0x100 to 0x300 */
  386.     imageDescriptionH = (ImageDescription **)NewHandle( 4 );    
  387. /* find needed buffer size: */
  388.     error = GetMaxCompressionSize(&pixMap,&frmRect,colorDepth,imageQuality,
  389.         codecType,codecID,&maxCompressedFrameSize); 
  390.     if (error) ExitToShell();
  391. /* Allocate frame buffer */
  392.     frameDatabitsH = NewHandle(maxCompressedFrameSize); 
  393.     if (!frameDatabitsH) ExitToShell();
  394.     HLock(frameDatabitsH);      /* lock handle to buffer */
  395. }
  396.  
  397. /*****************************************************************************
  398. * MakeMovieFrames() -- Create a unique series of movie frames using simple
  399. *  QuickDraw calls. Compress and add each frame to movie (gMovie). Stop when 
  400. *  max # of frames is reached
  401. ****************************************************/
  402. void MakeMovieFrames(void)
  403. {
  404.     long        i;     /* loop control */
  405.     Rect        r2, r3;    /* rects used in creating graphics image */
  406.     
  407.     for(i = 0; i<kFrameTotal; i++) /* loop until max# frames is created */
  408.     {
  409.         if(error!= noErr)                   
  410.             ExitToShell();
  411.  
  412. /* Draw a single frame. Uses QuickDraw calls to create graphics image */
  413.         SetGWorld(movieGWorld,nil);
  414.         EraseRect(&frmRect);    /* erase whole area to white */
  415.         r2 = frmRect;
  416.         r2.bottom = (short)((long)r2.bottom * i / (kFrameTotal-1));
  417.         InvertRect(&r2);   
  418.         r2 = frmRect;
  419.         FillOval(&r2, black);
  420.         InsetRect (&r2,i,i);
  421.         FillOval(&r2, white);
  422.         InsetRect (&r2,i+2,i+2);
  423.         InvertOval(&r2);   
  424.     SetRect(&r3,(frmRect.right - frmRect.left) / 2,(frmRect.bottom - 
  425.                                                              frmRect.top) / 2, 
  426.         (frmRect.right - frmRect.left) / 2,(frmRect.bottom - 
  427.                                                             frmRect.top) / 2 );
  428.         InsetRect(&r3,-(i*2),-(i*2));
  429.         FillOval(&r3,white);
  430. /* draw frame into the old Gworld so creation process can be viewed. 
  431. * done for visual feedback */
  432.         SetGWorld(oldGWorld,oldGDevice);
  433.         CopyBits((BitMap *) pixMap,(BitMap *) *(PixMapHandle)
  434.                         (qd.thePort->portBits.baseAddr),&frmRect,&frmRect,0,0);
  435. /* compress and add current frame to movie: */
  436.         AddMovieFrame();
  437.     }
  438. }
  439.  
  440. /*****************************************************************************
  441. * AddMovieFrame() -- Compress current frame then add it to our movies media. 
  442. *  This is done for each frame.
  443. *****************************************************************************/
  444. void AddMovieFrame(void) {      
  445. /* compress frame:  */
  446. error = CompressImage(pixMapH,&frmRect, imageQuality,,codecType 
  447.                            imageDescriptionH, StripAddress(*frameDatabitsH) );
  448.     compressedFrameSize = (**imageDescriptionH).dataSize;
  449.     if (error) ExitToShell();
  450. /* add single frame to media:*/     
  451. error = AddMediaSample(gMedia, frameDatabitsH, 0L, compressedFrameSize, 
  452.   (TimeValue)1, (SampleDescriptionHandle) imageDescriptionH, 1L, 0, &sampTime);
  453.     if (error) ExitToShell();
  454. }
  455.  
  456. /*****************************************************************************
  457. * QuickTimeCapable() -- Uses the Gestalt Manager to check if QuickTime is 
  458. *   available at runtime.  If not, return error. 
  459. *****************************************************************************/
  460. Boolean QuickTimeCapable() 
  461. {
  462.     long    response;
  463.     /* Test if QuickTime is available: */
  464.     error = Gestalt(gestaltQuickTime, &response);
  465.     if (error != 0)     /* error=0 if OK, else an error has occured */
  466.         return false;   /* if error, not QuickTime capable */
  467. /* if no error finding QuickTime, check for the ICM  */
  468.     error = Gestalt(gestaltCompressionMgr, &response);
  469.     if (error != 0)
  470.         return false;               
  471.     error = EnterMovies();/* Initialize Movie Toolbox */
  472.     if (error != 0)
  473.         return false;   /* error initalizing QuickTime */
  474.     else
  475.         return true;    /* QuickTime capable; ready to play movie */
  476. }           
  477.  
  478. /*****************************************************************************
  479. * CleanUp() -- Create a new movie file (gMovie) with associated track (gTrack) 
  480. *    and media (gMedia). Return error code if unable to complete process.
  481. *****************************************************************************/
  482. void CleanUp()
  483. {
  484.     short       resourceId = 1;
  485.     error = EndMediaEdits( gMedia );    /* finished adding samples */
  486.     if (error) ExitToShell();
  487. error = InsertMediaIntoTrack(gTrack,0L,0L,GetMediaDuration(gMedia),kFrameRate);
  488.     if (error) ExitToShell();
  489. error = AddMovieResource( gMovie, resRefNum, &resourceId, movieFSSpec.name );
  490.     if (error) ExitToShell();
  491. error = MakeFilePreview(resRefNum, (ProgressProcRecordPtr) -1); 
  492.     error = CloseMovieFile( resRefNum );
  493.     if (error) ExitToShell();
  494.     DisposeMovie(gMovie);       /* We don't need the movie anymore */
  495.     DisposHandle(frameDatabitsH);   /* dispose frame buffer memory */
  496.     DisposHandle((Handle)imageDescriptionH); /* and other storage: */
  497.     DisposeGWorld(movieGWorld);
  498.     ExitMovies();                           
  499. }
  500.  
  501.     
  502.  
  503.  
  504.